﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp220920
{
    internal class Calendar
    {
        static void Main(string[] args)
        {
            //设置每月月历的宽度、高度
            const int monthWidth = 40;
            const int monthHigth = 8;
            //设置初始日期
            DateTime iDay = new DateTime(2022, 1, 1);
            //逐个输出每个月份的月历
            int x = 0, y = 0;
            for (; iDay.Year ==2022; iDay =iDay.AddMonths(1))
            {   
                //输出表头
                x=((iDay.Month-1)%3)*monthWidth;
                y=((iDay.Month-1)/3)*monthHigth;
                Console.SetCursorPosition(x, y);
                Console.Write("           "+iDay.Month +"月");
                Console.SetCursorPosition(x, y+1);
                Console.Write("日  一  二  三  四  五  六 ");

                //获取每月首天是星期几之后确定光标x、y坐标
                int week = GetWeekByDay(iDay.Year, iDay.Month, iDay.Day);
                x = ((iDay.Month-1)%3)*monthWidth+week*4;
                y=(iDay.Month-1)/3*monthHigth+2;
                //设置光标位置
                Console.SetCursorPosition(x, y);   
                //count1代表每月首天是星期几
                int count1=GetWeekByDay(iDay.Year, iDay.Month, iDay.Day);

                //输出日
                int nChange = 0;
                for (int count2 = 1; count2<=GetMonthdDay(iDay.Year, iDay.Month); count2++)
                {
                    
                    //每到周六改变光标位置                    
                    if ((count1+count2-1)%7==0)                 
                    {
                        if (count1==0)             //解决五月份count1==0但满足换行条件从而意外换行的问题
                        {
                            int a = ((iDay.Month-1)%3)*monthWidth;
                            int b = ((iDay.Month-1)/3)*monthHigth+nChange+2;
                            Console.SetCursorPosition(a, b);
                            nChange++;
                        }
                        else if (count1!=0)        //其余月份
                        {
                            nChange++;
                            int a = ((iDay.Month-1)%3)*monthWidth;
                            int b = ((iDay.Month-1)/3)*monthHigth+nChange+2;
                            Console.SetCursorPosition(a, b);
                        }
                     }
                    //确定某天光标位置后输出
                    switch (count2)
                    {
                        case <10:
                            Console.Write(count2+"   ");
                            break;
                        case >=10:
                            Console.Write(count2+"  ");
                            break;
                     }
                }

            }
            //调试控制台结束时的语句覆盖了部分输出内容，故换两次行
            Console.WriteLine();
            Console.WriteLine();
        }
        //函数1：输入年月日以得到这天是星期几
        private static int GetWeekByDay(int year, int month, int day)
        {
            DateTime dt = new DateTime(year, month, day);
            return Convert.ToInt32(dt.DayOfWeek);                          //DayOfWeek
        }
        //函数2：获取某年某月的天数
        private static int GetMonthdDay(int year, int month)
        {
            int thisMonthDays = DateTime.DaysInMonth(year, month);        //DaysInMonth
            return Convert.ToInt32(thisMonthDays);
        }

    }
}
